require 'game_information'

class Game

  attr_accessor :commentary
  
  RESOURCES_REQUIRED_FOR_FARMER = 5
  RESOURCES_REQUIRED_FOR_BARRACK = 100
  RESOURCES_REQUIRED_FOR_WARRIOR = 30
  POPULATION_LIMIT = 200
  FARM_PRODUCE = 6
  MAXIMUM_FARMS = 8
  MAXIMUM_RESOURCES = 50000
  $mutex = Mutex.new
    
  def initialize
    @stats = Hash.new
    @commentary = Array.new
  end
  
  def add_achievement message 
    @commentary << message
  end
  
  def self.instance
    $mutex.synchronize do 
      if $game.nil?
        p "game is null #{@game}"
        $game= Game.new
      end
      p $game
      $game
    end
  end
  
  def new
    raise "Error: Its a Singleton class. Use instance."
  end
  
  def add_player name
    @stats[name.intern]=GameInformation.new
  end
  
  def create_farmer name
#    sleep 1
    player_stats = @stats[name.intern]
    if player_stats.resources > RESOURCES_REQUIRED_FOR_FARMER && player_stats.total_population < POPULATION_LIMIT
      player_stats.farmers+=1  
      player_stats.resources-= RESOURCES_REQUIRED_FOR_FARMER
      player_stats.status = "Creating farmers"
    else
      player_stats.status = "Can't create any more farmers. Not enough resources"
    end
  end
  
  def build_barrack name
#    sleep 5
    player_stats = @stats[name.intern]
    if player_stats.barracks == 0 && player_stats.resources > RESOURCES_REQUIRED_FOR_BARRACK
      player_stats.barracks+=1
      player_stats.resources-= RESOURCES_REQUIRED_FOR_BARRACK
      player_stats.status = "Building barrack"
      @commentary << "#{name} has built a barrack"
    else
      player_stats.status = "Can't create barrack. Not enough resources or maybe you have one already"
    end
  end
  
  def farm name
#    sleep 2
    player_stats = @stats[name.intern]
    if player_stats.farms < MAXIMUM_FARMS
      add_resources name, (player_stats.farmers * FARM_PRODUCE)
      player_stats.farms+=1
      player_stats.status = "Farming"
    else
      player_stats.farmers-=1 unless player_stats.farmers == 0
      player_stats.farms-=1 unless player_stats.farms == 0     
      player_stats.status = "Your farmers have started dying now... Create more"
    end
  end
  
  def add_resources name, count
    player_stats = @stats[name.intern]
    player_stats.resources += count
    player_stats.resources = MAXIMUM_RESOURCES if player_stats.resources > MAXIMUM_RESOURCES
  end
  
  def create_warrior name
#    sleep 3
    player_stats = @stats[name.intern]
    if player_stats.barracks > 0 && player_stats.resources > RESOURCES_REQUIRED_FOR_WARRIOR && player_stats.total_population < POPULATION_LIMIT
      player_stats.warriors+=1
      player_stats.resources-= RESOURCES_REQUIRED_FOR_WARRIOR
      player_stats.status = "Creating Warriors"
    else
      player_stats.status = "Can't create warriors. Mostly because resources are not enough... BTW have you built a barrack??"
    end    
  end
  
  def set_status name, status
    @stats[name.intern].status = status
  end
  
  def get_status name
    player_stats = @stats[name.intern]
    "#{player_stats.farmers} farmers, #{player_stats.warriors} warriors, #{player_stats.resources} resources, <b>#{player_stats.status}</b>, <font color=\"red\"><b>#{player_stats.warning}</b></font>"
  end
  
  def attack name, target_player_name
    @commentary << "#{name} is attacking #{target_player_name}"
    player_stats = @stats[name.intern]
    target_player_stats = @stats[target_player_name.intern]
    if target_player_stats.nil?
      player_stats.status = "#{target_player_name} not playing. Is the name correct?"
    end
    
    @attacking_warriors = player_stats.warriors
    @defending_warriors = target_player_stats.warriors
    
    if @attacking_warriors > @defending_warriors
      target_player_stats.warning = "#{name} is attacking you!!! Save yourself if you can..."
      player_stats.status = "Attacking #{target_player_name}"
#      sleep 10
      
      @extra_attacking_warriors = @attacking_warriors - @defending_warriors
      attack_equal(@attacking_warriors - @extra_attacking_warriors, name, target_player_name)
      attack_zero(@extra_attacking_warriors, name, target_player_name)
            
    elsif @attacking_warriors == @defending_warriors
      target_player_stats.warning = "#{name} is attacking you!!! Save yourself if you can..."
      player_stats.status = "Attacking #{target_player_name}"
#      sleep 10
      
      attack_equal(@attacking_warriors, name, target_player_name)
           
    else
      player_stats.status = "Dude!! You attacked the wrong guy"
      attack target_player_name, name
    end
  end
  
  def attack_equal warriors, name, target_player_name
    player_stats = @stats[name.intern]
    target_player_stats = @stats[target_player_name.intern]
    
    player_stats.warriors -= warriors*4/10
    target_player_stats.warriors -= warriors*6/10
    
    target_player_stats.farmers -= warriors
#    @stats[target_player_name.intern].resources -= warriors
    
    target_player_stats.rationalize_damage
  end
  
  def attack_zero warriors, name, target_player_name
    target_player_stats = @stats[target_player_name.intern]

    target_player_stats.farmers -= warriors*10
    target_player_stats.resources -= warriors*30
    
    target_player_stats.rationalize_damage
  end
  
  def scores
    @scores = Hash.new
    @stats.each_key do | player |
      @points = @stats[player].score      
      @scores[player] = @points      
    end
    return @scores
  end
  
  def get_farmers name
    @stats[name.intern].farmers
  end
  
  def get_warriors name
    @stats[name.intern].warriors
  end
  
  def get_resources name
    @stats[name.intern].resources
  end
  
  def gift_warriors name, receiver_name, count
    if @stats[name.intern].warriors > count 
      @stats[name.intern].warriors-=count
      @stats[receiver_name.intern].warriors+=count
    end
    # gift :warriors, name, receiver_name, count
  end

  def gift_resources name, receiver_name, count
    if @stats[name.intern].resources > count
      @stats[name.intern].resources-=count  
      @stats[receiver_name.intern].resources+=count
    end
  end
  
  def gift what,  name, receiver_name, count
    senders_what=stats[name.intern].send what
    if senders_what > count
      senders_what-=count
      receivers_what=stats[receiver_name.intern].send what
      receivers_what+=count
      
      stats[name.intern].send "#{what}=", senders_what
      stats[receiver_name.intern].send "#{what}=", receivers_what
    end
  end
  
  def clear_warning name
    player_stats = @stats[name.intern]
    player_stats.warning = ""
  end
end